#ifndef __H_GAME_H__
#define __H_GAME_H__

#include <deque>
#include <vector>
#include <map>
#include <set>
#include "ICC_Timer_Handler.h"
#include "RedisClient.h"
#include "GameBase.h"
#include "DbPart.h"
#include "CClient.h"
#include "def.h"
#include "LogicData.h"
#include "HostBase.h"
#include <thread>
#include <rabbitmq-c/amqp.h>
#include <rabbitmq-c/tcp_socket.h>

class CHost;

const unsigned int g_uid_mod = 100;
const unsigned int g_record_count_mod = 20;
const unsigned int g_cache_dur = 172800;
const unsigned int g_redis_dayamount_dur = 172800;

class CGameServer : public BYTimerOject
{
	struct stRecordCache
	{
		_u64_ m_lastflowtime;
		unsigned int m_count;
		unsigned int m_lastday;
		int64 m_dayamountbet;
		int64 m_dayamountwin;
		 
		stRecordCache():m_lastflowtime(0), m_count(0), m_dayamountbet(0), m_dayamountwin(0), m_lastday(0)
		{
		}
		stRecordCache(const stRecordCache& other)
		{
			m_lastflowtime = other.m_lastflowtime;
			m_count = other.m_count;
			m_lastday = other.m_lastday;
			m_dayamountbet = other.m_dayamountbet;
			m_dayamountwin = other.m_dayamountwin;
		}

		stRecordCache& operator = (const stRecordCache& other)
		{
			if (this == &other)
				return *this;

			m_lastflowtime = other.m_lastflowtime;
			m_count = other.m_count;
			m_lastday = other.m_lastday;
			m_dayamountbet = other.m_dayamountbet;
			m_dayamountwin = other.m_dayamountwin;

			return *this;
		}
	};

public:
	CGameServer();
	virtual ~CGameServer();
public:
	virtual bool InitGame();
	virtual int OnBYTimeOut(int Timerid);
	int ProcessPacket(SocketHandler * pHandler, NETInputPacket* inputPkg);
	int ProcEventPublishService(int ev_id, SpiderEvent* pEvent);
	int ProcEventGameInit(int ev_id, SpiderEvent* pEvent);
private:
	void run(void);
	int procMessage(const char* data, const unsigned int len);
	bool initmq(void);
	bool mqbind(void);
	void releasemq(void);
	bool monthdis(const std::string& m1, const std::string& m2, int& dis);
	int caclym(const std::string& tname, const unsigned int game, const time_t tt, const int timezoneinmin, std::string& ym, unsigned int& mseq);
	bool ReadCommonConf(const char* strxml);
	int procTimerCacheCheck(void);
	void chachCheck(void);
	void monthlistTable(const unsigned int game, std::string& tablename);
    void gamerecordCountTable(const unsigned int game, const unsigned int mod, const unsigned int uid, std::string& tablename);
	void redisDayAmountKey(const unsigned int uid, const unsigned int game, const unsigned int ymd, std::string& rkey);

    std::map<std::string, int> m_dictareatimezoneinmin;
	std::vector<std::string> m_dayamountfield;
    std::map<unsigned int, std::string> m_agencyarea;
	std::set<std::string> m_monthlistables;
	std::set<std::string> m_gamerecordcounttables;
	std::set<std::string> m_recordtables;
	std::map<unsigned int, std::map<std::string, unsigned int> > m_gamemindex;
	std::map<unsigned int, std::map<unsigned int, std::string> > m_gameindexm;
	std::map<unsigned int, std::pair<std::string, unsigned int> > m_gamefirstm;
	std::map<unsigned int, std::map<unsigned int, stRecordCache> > m_recordcache;

	std::thread* m_pthread;
	unsigned int m_nodecount;
	int m_nodeindex;
	volatile bool m_exitflag;
	std::string m_mqIp;
	unsigned short m_mqPort;
	std::string m_mqVhost;
	std::string m_mqUsername;
	std::string m_mqPwd;
	amqp_connection_state_t m_mqconn;
	int m_mqchannel;
	static char* s_szexchange;
	static char* s_szqueue;

	bool m_initflag;
	volatile bool m_cachecheckflag;
public:
	CHost* m_pHost;
	CDbPart m_dbHandler;
	CDbPart m_dbHandlerAssistant;
	CDbPart m_dbHandlerMaintenance;
	CDbPart m_dbHandlerAgency;
	RedisClient* m_gamerecordRedis;
};


#endif


